﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

//------------------------------------------------------------
// shaco Framework
// Copyright © 2017-2021 chang.liu All rights reserved.
// Feedback: 449612236@qq.com
//------------------------------------------------------------

namespace shacoEditor
{
    public class DataSavePreviewWindow : EditorWindow
    {
        private enum PreviewMode
        {
            FrameworkDataSave,
            PlayerPrefs,
            EditorPrefs
        }


        [System.Serializable]
        private class KeyValuePair
        {
            public string Key = string.Empty;
            public object Value = string.Empty;
        }

        private static class PlayerPrefsExtension
        {
            static public List<KeyValuePair> GetAll(string prefsPath, bool isEditor)
            {
                if (Application.platform == RuntimePlatform.OSXEditor)
                {
                    // Parse the player prefs file if it exists
                    if (System.IO.File.Exists(prefsPath))
                    {
                        // Parse the plist then cast it to a Dictionary
                        object plist = shaco.iOS.XcodeEditor.PlistCS.Plist.readPlist(prefsPath);

                        Dictionary<string, object> parsed = plist as Dictionary<string, object>;

                        // Convert the dictionary data into an array of PlayerPrefPairs
                        var tempPlayerPrefs = new List<KeyValuePair>();
                        int i = 0;
                        foreach (KeyValuePair<string, object> pair in parsed)
                        {
                            var valueType = pair.Value.GetType();
                            if (valueType == typeof(double) || valueType == typeof(float))
                            {
                                // Some float values may come back as double, so convert them back to floats
                                tempPlayerPrefs.Add(new KeyValuePair() { Key = pair.Key, Value = (float)pair.Value });
                            }
                            else
                            {
                                tempPlayerPrefs.Add(new KeyValuePair() { Key = pair.Key, Value = pair.Value });
                            }

                            i++;
                        }

                        // Return the results
                        return tempPlayerPrefs;
                    }
                    else
                    {
                        // No existing player prefs saved (which is valid), so just return an empty array
                        return new List<KeyValuePair>();
                    }
                }
                else if (Application.platform == RuntimePlatform.WindowsEditor)
                {
                    // From Unity docs: On Windows, PlayerPrefs are stored in the registry under HKCU\Software\[company name]\[product name] key, where company and product names are the names set up in Project Settings.
#if UNITY_5_5_OR_NEWER
                    // From Unity 5.5 editor player prefs moved to a specific location
                    var registryKey =
                        Microsoft.Win32.Registry.CurrentUser.OpenSubKey(prefsPath);
#else
                    var registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path);
#endif

                    // Parse the registry if the specified registryKey exists
                    if (registryKey != null)
                    {
                        // Get an array of what keys (registry value names) are stored
                        string[] valueNames = registryKey.GetValueNames();

                        // Create the array of the right size to take the saved player prefs
                        var tempPlayerPrefs = new List<KeyValuePair>();

                        // Parse and convert the registry saved player prefs into our array
                        int i = 0;
                        foreach (string valueName in valueNames)
                        {
                            string key = valueName;

                            // Remove the _h193410979 style suffix used on player pref keys in Windows registry
                            int index = key.LastIndexOf("_");
                            if (index > 0)
                                key = key.Remove(index, key.Length - index);

                            // Get the value from the registry
                            object ambiguousValue = registryKey.GetValue(valueName);

                            // Unfortunately floats will come back as an int (at least on 64 bit) because the float is stored as
                            // 64 bit but marked as 32 bit - which confuses the GetValue() method greatly! 
                            if (ambiguousValue is int || ambiguousValue is long)
                            {
                                // If the player pref is not actually an int then it must be a float, this will evaluate to true
                                // (impossible for it to be 0 and -1 at the same time)
                                if (isEditor)
                                {
                                    if (EditorPrefs.GetInt(key, -1) == -1 && EditorPrefs.GetInt(key, 0) == 0)
                                    {
                                        // Fetch the float value from PlayerPrefs in memory
                                        ambiguousValue = EditorPrefs.GetFloat(key);
                                    }
                                }
                                else
                                {
                                    if (PlayerPrefs.GetInt(key, -1) == -1 && PlayerPrefs.GetInt(key, 0) == 0)
                                    {
                                        // Fetch the float value from PlayerPrefs in memory
                                        ambiguousValue = PlayerPrefs.GetFloat(key);
                                    }
                                }
                            }
                            else if (ambiguousValue is byte[])
                            {
                                // On Unity 5 a string may be stored as binary, so convert it back to a string
                                ambiguousValue = System.Text.Encoding.Default.GetString((byte[])ambiguousValue);
                            }

                            // Assign the key and value into the respective record in our output array
                            // Some float values may come back as double, so convert them back to floats
                            tempPlayerPrefs.Add(new KeyValuePair() { Key = key, Value = ambiguousValue });
                            i++;
                        }

                        // Return the results
                        registryKey.Close();
                        return tempPlayerPrefs;
                    }
                    else
                    {
                        // No existing player prefs saved (which is valid), so just return an empty array
                        return new List<KeyValuePair>();
                    }
                }
                else
                {
                    throw new System.NotSupportedException("PlayerPrefsEditor doesn't support this Unity Editor platform");
                }
            }

            public static List<KeyValuePair> GetAllPlayerPrefs()
            {
                var companyName = PlayerSettings.companyName;
                var productName = PlayerSettings.productName;

                if (Application.platform == RuntimePlatform.OSXEditor)
                {
                    // Construct the plist filename from the project's settings
                    string plistFilename = string.Format("unity.{0}.{1}.plist", companyName, productName);
                    // Now construct the fully qualified path
                    string playerPrefsPath = System.IO.Path.Combine(System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Library/Preferences"),
                        plistFilename);
                    return GetAll(playerPrefsPath, false);
                }
                else if (Application.platform == RuntimePlatform.WindowsEditor)
                {
#if UNITY_5_5_OR_NEWER
                    // From Unity 5.5 editor player prefs moved to a specific location
                    return GetAll("Software\\Unity\\UnityEditor\\" + companyName + "\\" + productName, false);
#else
                    return GetAll("Software\\" + companyName + "\\" + productName, false);
#endif
                }
                else
                {
                    throw new System.NotSupportedException("PlayerPrefsEditor doesn't support this Unity Editor platform");
                }
            }

            public static List<KeyValuePair> GetAllEditorPrefs()
            {
                var unityVersionName = "Unity Editor 5.x";//Application.unityVersion;

                if (Application.platform == RuntimePlatform.OSXEditor)
                {
                    // Construct the plist filename from the project's settings
                    string plistFilename = string.Format("com.unity3d.{0}.plist", unityVersionName);
                    // Now construct the fully qualified path
                    string playerPrefsPath = System.IO.Path.Combine(System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Library/Preferences"),
                        plistFilename);
                    return GetAll(playerPrefsPath, true);
                }
                else if (Application.platform == RuntimePlatform.WindowsEditor)
                {
                    return GetAll("Software\\Unity Technologies\\" + unityVersionName, true);
                }
                else
                {
                    throw new System.NotSupportedException("PlayerPrefsEditor doesn't support this Unity Editor platform");
                }
            }
        }

        private Vector2 _scrollPosition = Vector2.zero;
        private PreviewMode _previewMode = PreviewMode.FrameworkDataSave;
        private Dictionary<string, int> _keyToIndex = new Dictionary<string, int>();
        private List<KeyValuePair> _keyValuePairs = new List<KeyValuePair>();
        private List<KeyValuePair> _keyValuePairsSearching = new List<KeyValuePair>();
        [SerializeField]
        private KeyValuePair _newKeyValue = new KeyValuePair();
        private bool _isDuplicateNewKey = false;
        private Queue<string> _willDeleteKey = new Queue<string>();
        private string _searchName = string.Empty;
        private const int _maxShowCountInPerPage = 50;
        private int _currentPageIndex = 0;
        private string _dataPath = string.Empty;

        [MenuItem("shaco/Tools/DataSavePreview _F12", false, (int)ToolsGlobalDefine.MenuPriority.Tools.ASSETBUNDLE_VIEWER)]
        static public void OpenDataSavePreviewWindow()
        {
            shacoEditor.EditorHelper.GetWindow<DataSavePreviewWindow>(null, true, "DataSavePreview");
        }

        private void OnEnable()
        {
            shacoEditor.EditorHelper.GetWindow<DataSavePreviewWindow>(this, true, "DataSavePreview").Init();
        }

        private void OnDestroy()
        {
            SaveSettings();
        }

        private void Init()
        {
            LoadSettings();
        }

        void SaveSettings()
        {
            shaco.GameHelper.datasave.WriteEnum("DataSavePreviewWindow.PreviewMode", _previewMode);
        }

        void LoadSettings()
        {
            _previewMode = shaco.GameHelper.datasave.ReadEnum<PreviewMode>("DataSavePreviewWindow.PreviewMode", PreviewMode.FrameworkDataSave);
            OnPreviewModeChanged();
        }

        private void OnGUI()
        {
            EditorHelper.ShowDefaultWindowContextMenuHandling();
            UpdateEvent();

            DrawDataPath();
            DrawPageJump();

            EditorGUI.BeginChangeCheck();
            {
                _previewMode = (PreviewMode)EditorGUILayout.EnumPopup("Preview Mode", _previewMode);
            }
            if (EditorGUI.EndChangeCheck())
            {
                OnPreviewModeChanged();
            }

            GUILayout.BeginHorizontal();
            {
                if (string.IsNullOrEmpty(_searchName))
                    GUILayout.Label("Total Count: " + _keyValuePairs.Count);
                else
                    GUILayout.Label("Search Count: " + _keyValuePairsSearching.Count);

                if (GUILayout.Button("Delete All Save Data"))
                {
                    if (EditorUtility.DisplayDialog("Warning", "Are you sure you want to delete all save data ?", "OK", "Cancel"))
                    {
                        switch (_previewMode)
                        {
                            case PreviewMode.FrameworkDataSave: shaco.GameHelper.datasave.Clear(); break;
                            case PreviewMode.PlayerPrefs: PlayerPrefs.DeleteAll(); break;
                            case PreviewMode.EditorPrefs: EditorPrefs.DeleteAll(); break;
                            default: Debug.LogError("DataSavePreviewWindow OnGUI error: unsupport type=" + _previewMode); break;
                        }
                        OnPreviewModeChanged();
                        Debug.Log("Delete save data success...");
                    }
                }

                GUILayout.FlexibleSpace();
                GUI.changed = false;
                _searchName = GUILayoutHelper.SearchField(_searchName, GUILayout.Width(Screen.width / 3 * 1));
                if (GUI.changed)
                {
                    var searchNameLower = _searchName.ToLower();
                    UpdateSearchContent(searchNameLower);
                }
            }
            GUILayout.EndHorizontal();

            _scrollPosition = GUILayout.BeginScrollView(_scrollPosition);
            {
                DrawPreviewData();
                DrawAddData();
            }
            GUILayout.EndScrollView();
        }

        private void UpdateSearchContent(string searchNameLower)
        {
            _keyValuePairsSearching.Clear();
            if (string.IsNullOrEmpty(searchNameLower))
                return;

            for (int i = 0; i < _keyValuePairs.Count; ++i)
            {
                if (_keyValuePairs[i].Key.ToLower().Contains(searchNameLower))
                    _keyValuePairsSearching.Add(_keyValuePairs[i]);
            }
        }

        private List<KeyValuePair> GetCurrentPairs()
        {
            return string.IsNullOrEmpty(_searchName) ? _keyValuePairs : _keyValuePairsSearching;
        }

        private void UpdateEvent()
        {
            var currentEvent = Event.current;
            if (null == currentEvent)
                return;

            switch (currentEvent.type)
            {
                case EventType.KeyDown:
                    {
                        if (currentEvent.control || currentEvent.command)
                        {
                            if (currentEvent.keyCode == KeyCode.LeftArrow)
                            {
                                if (_currentPageIndex > 0)
                                {
                                    --_currentPageIndex;
                                    this.Repaint();
                                }
                            }
                            if (currentEvent.keyCode == KeyCode.RightArrow)
                            {
                                var maxPageCount = GetCurrentPairs().Count / _maxShowCountInPerPage;
                                if (_currentPageIndex < maxPageCount)
                                {
                                    ++_currentPageIndex;
                                    this.Repaint();
                                }
                            }
                        }
                        break;
                    }
            }
        }

        private void DrawDataPath()
        {
            GUILayout.BeginHorizontal();
            {
                EditorGUI.BeginDisabledGroup(true);
                {
                    EditorGUILayout.TextField("Data Path", _dataPath);
                }
                EditorGUI.EndDisabledGroup();
                if (GUILayout.Button("Open", GUILayout.Width(80)))
                {
                    if (Application.platform == RuntimePlatform.OSXEditor || _previewMode == PreviewMode.FrameworkDataSave)
                        EditorHelper.ShowInFolder(_dataPath);
                    else if (Application.platform == RuntimePlatform.WindowsEditor)
                    {
                        //打开注册表并定位到指定key
                        var registryLastKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit";
                        Microsoft.Win32.Registry.SetValue(registryLastKey, "LastKey", _dataPath);
                        System.Diagnostics.Process.Start("C:/Windows/regedit.exe");
                    }
                    else
                        Debug.LogError("unsupport platform: " + Application.platform);
                }
            }
            GUILayout.EndHorizontal();
        }

        private void DrawPageJump()
        {
            GUILayout.BeginHorizontal();
            {
                EditorGUI.BeginDisabledGroup(_currentPageIndex <= 0);
                {
                    if (GUILayout.Button("<<(0)"))
                    {
                        _currentPageIndex = 0;
                    }
                    if (GUILayout.Button("<(Ctrl + Left Arrow)"))
                    {
                        --_currentPageIndex;
                    }
                }
                EditorGUI.EndDisabledGroup();

                var maxPageCount = GetCurrentPairs().Count / _maxShowCountInPerPage;
                GUI.skin.label.alignment = TextAnchor.MiddleCenter;
                GUILayout.Label($"{_currentPageIndex}/{maxPageCount}", GUILayout.Width(50));

                EditorGUI.BeginDisabledGroup(_currentPageIndex >= maxPageCount);
                {
                    if (GUILayout.Button(">(Ctrl + Right Arrow)"))
                    {
                        ++_currentPageIndex;
                    }
                    if (GUILayout.Button($">>({maxPageCount})"))
                    {
                        _currentPageIndex = maxPageCount;
                    }
                }
                EditorGUI.EndDisabledGroup();
            }
            GUILayout.EndHorizontal();
        }

        private void DrawPreviewData()
        {
            var currentPairs = GetCurrentPairs();
            var parisCount = currentPairs.Count;
            var startIndex = Mathf.Min(_currentPageIndex * _maxShowCountInPerPage, parisCount - _maxShowCountInPerPage);
            var endIndex = Mathf.Min(startIndex + _maxShowCountInPerPage, parisCount, parisCount);

            if (startIndex < 0)
                _currentPageIndex = startIndex = 0;

            for (int i = startIndex; i < endIndex; ++i)
            {
                var iter = currentPairs[i];
                GUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("-", GUILayout.Width(16)))
                    {
                        _willDeleteKey.Enqueue(iter.Key);
                        GUI.FocusControl(string.Empty);
                    }

                    EditorGUI.BeginChangeCheck();
                    {
                        DrawKey(iter.Key);
                        DrawValue(iter);
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        SetKeyValue(iter, false);
                    }
                }
                GUILayout.EndHorizontal();
            }

            if (_willDeleteKey.Count > 0)
            {
                foreach (var iter in _willDeleteKey)
                    DeleteKey(iter);
                _willDeleteKey.Clear();
                _isDuplicateNewKey = _keyToIndex.ContainsKey(_newKeyValue.Key);
            }
        }

        private void DrawAddData()
        {
            GUILayout.BeginHorizontal();
            {
                EditorGUI.BeginDisabledGroup(_isDuplicateNewKey || string.IsNullOrEmpty(_newKeyValue.Key));
                {
                    var oldColor = GUI.color;
                    GUI.color = _isDuplicateNewKey || string.IsNullOrEmpty(_newKeyValue.Key) ? Color.gray : Color.green;
                    if (GUILayout.Button("+", GUILayout.Width(16)))
                    {
                        SetKeyValue(_newKeyValue, true);
                        _newKeyValue = new KeyValuePair();
                        GUI.FocusControl(string.Empty);
                        _scrollPosition.y += 24; //滚动条自动向下滚动点，保持刚好看到+按钮位置
                    }
                    GUI.color = oldColor;
                }
                EditorGUI.EndDisabledGroup();

                EditorGUI.BeginChangeCheck();
                {
                    _newKeyValue.Key = DrawKey(_newKeyValue.Key);
                }
                if (EditorGUI.EndChangeCheck())
                {
                    _isDuplicateNewKey = _keyToIndex.ContainsKey(_newKeyValue.Key);
                }

                if (_isDuplicateNewKey)
                {
                    var oldColor = GUI.color;
                    GUI.color = Color.red;
                    GUILayout.Label("Duplicate Key");
                    GUI.color = oldColor;
                }
                else
                    DrawValue(_newKeyValue);
            }
            GUILayout.EndHorizontal();
        }

        private string DrawKey(string key)
        {
            GUILayout.Label("KEY", GUILayout.ExpandWidth(false));
            return EditorGUILayout.TextArea(key, GUILayout.Width(Screen.width / 3));
        }

        private void DrawValue(KeyValuePair keyValue)
        {
            var valueWidth = GUILayout.Width(Screen.width / 3 * 2 - 120);
            GUILayout.Label(keyValue.Value.GetType().Name, GUILayout.Width(50));
            keyValue.Value = GUILayoutHelper.DrawValue(string.Empty, keyValue.Value, keyValue.Value.GetType(), null, valueWidth);
        }

        private void OnPreviewModeChanged()
        {
            _keyValuePairs.Clear();
            _keyToIndex.Clear();
            _searchName = string.Empty;

            switch (_previewMode)
            {
                case PreviewMode.FrameworkDataSave:
                    {
                        _dataPath = shaco.GameHelper.datasave.savePath;
                        var allKey = shaco.GameHelper.datasave.GetAllKey();

                        foreach (var iter in allKey)
                        {
                            var value = shaco.GameHelper.datasave.ReadString(iter);
                            bool boolParse;
                            int intParse;
                            float floatParse;
                            var newKeyValue = new KeyValuePair() { Key = iter };
                            if (bool.TryParse(value, out boolParse))
                            {
                                newKeyValue.Value = boolParse;
                            }
                            else if (int.TryParse(value, out intParse))
                            {
                                newKeyValue.Value = intParse;
                            }
                            else if (float.TryParse(value, out floatParse))
                            {
                                newKeyValue.Value = floatParse;
                            }
                            else
                            {
                                newKeyValue.Value = value;
                            }

                            _keyValuePairs.Add(newKeyValue);
                            _keyToIndex.Add(iter, _keyValuePairs.Count - 1);
                        }
                        break;
                    }
                case PreviewMode.PlayerPrefs:
                    {
                        if (Application.platform == RuntimePlatform.OSXEditor)
                        {
                            string plistFilename = string.Format("unity.{0}.{1}.plist", PlayerSettings.companyName, PlayerSettings.productName);
                            string playerPrefsPath = System.IO.Path.Combine(System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Library/Preferences"),
                                plistFilename);
                            _dataPath = playerPrefsPath;
                        }
                        else if (Application.platform == RuntimePlatform.WindowsEditor)
                        {
#if UNITY_5_5_OR_NEWER
                            _dataPath = "HKEY_CURRENT_USER\\Software\\Unity\\UnityEditor\\" + PlayerSettings.companyName + "\\" + PlayerSettings.productName;
#else
                            _dataPath = "HKEY_CURRENT_USER\\Software\\" + PlayerSettings.companyName + "\\" + PlayerSettings.productName;
#endif
                        }
                        else
                            _dataPath = "Unsupport runtime platform: " + Application.platform;

                        var allKeyValue = PlayerPrefsExtension.GetAllPlayerPrefs();
                        foreach (var iter in allKeyValue)
                        {
                            _keyValuePairs.Add(iter);
                            _keyToIndex.Add(iter.Key, _keyValuePairs.Count - 1);
                        }
                        break;
                    }
                case PreviewMode.EditorPrefs:
                    {
                        if (Application.platform == RuntimePlatform.OSXEditor)
                        {
                            string plistFilename = string.Format("unity.{0}.{1}.plist", PlayerSettings.companyName, PlayerSettings.productName);
                            string playerPrefsPath = System.IO.Path.Combine(System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Library/Preferences"),
                                plistFilename);
                            _dataPath = playerPrefsPath;
                        }
                        else if (Application.platform == RuntimePlatform.WindowsEditor)
                        {
                            _dataPath = "HKEY_CURRENT_USER\\Software\\Unity Technologies\\Unity Editor 5.x";
                        }
                        else
                            _dataPath = "Unsupport runtime platform: " + Application.platform;

                        var allKeyValue = PlayerPrefsExtension.GetAllEditorPrefs();
                        foreach (var iter in allKeyValue)
                        {
                            _keyValuePairs.Add(iter);
                            _keyToIndex.Add(iter.Key, _keyValuePairs.Count - 1);
                        }
                        break;
                    }
                default: Debug.LogError("DataSavePreviewWindow OnPreviewDataChanged error: unsupport type=" + _previewMode); break;
            }
        }

        private void DeleteKey(string key)
        {
            switch (_previewMode)
            {
                case PreviewMode.FrameworkDataSave:
                    {
                        shaco.GameHelper.datasave.Remove(key);
                        break;
                    }
                case PreviewMode.PlayerPrefs:
                    {
                        PlayerPrefs.DeleteKey(key);
                        PlayerPrefs.Save();
                        break;
                    }
                case PreviewMode.EditorPrefs:
                    {
                        EditorPrefs.DeleteKey(key);
                        break;
                    }
                default: Debug.LogError("DataSavePreviewWindow DeleteKey error: unsupport type=" + _previewMode); return;
            }

            if (!_keyToIndex.ContainsKey(key))
            {
                Debug.LogError("DataSavePreviewWindow DeleteKey error: not found remove key=" + key);
                return;
            }
            var index = _keyToIndex[key];
            _keyValuePairs.RemoveAt(index);

            _keyToIndex.Clear();
            for (int i = _keyValuePairs.Count - 1; i >= 0; --i)
                _keyToIndex.Add(_keyValuePairs[i].Key, i);

            if (!string.IsNullOrEmpty(_searchName))
            {
                var index2 = _keyValuePairsSearching.IndexOf(v => v.Key == key);
                if (index2 < 0)
                    Debug.LogError("DataSavePreviewWindow DeleteKey error: not found remove search key=" + key);
                else
                    _keyValuePairsSearching.RemoveAt(index2);
            }
        }

        private void SetKeyValue(KeyValuePair keyValue, bool isAutoSetType)
        {
            if (!_keyToIndex.ContainsKey(keyValue.Key))
            {
                _keyValuePairs.Add(keyValue);
                _keyToIndex.Add(keyValue.Key, _keyValuePairs.Count - 1);
            }

            var valueString = keyValue.Value.ToString();
            if (isAutoSetType)
            {
                int intParse = 0;
                float floatParse = 0;
                if (int.TryParse(valueString, out intParse))
                {
                    keyValue.Value = intParse;
                }
                else if (float.TryParse(valueString, out floatParse))
                {
                    keyValue.Value = floatParse;
                }
                else
                {
                    keyValue.Value = valueString;
                }
            }

            switch (_previewMode)
            {
                case PreviewMode.FrameworkDataSave:
                    {
                        bool boolParse = false;
                        if (bool.TryParse(valueString, out boolParse))
                        {
                            keyValue.Value = boolParse;
                        }
                        shaco.GameHelper.datasave.WriteString(keyValue.Key, valueString);
                        break;
                    }
                case PreviewMode.PlayerPrefs:
                    {
                        var valueType = keyValue.Value.GetType();
                        if (valueType == typeof(int))
                            PlayerPrefs.SetInt(keyValue.Key, (int)keyValue.Value);
                        else if (valueType == typeof(float))
                            PlayerPrefs.SetFloat(keyValue.Key, (float)keyValue.Value);
                        else
                            PlayerPrefs.SetString(keyValue.Key, valueString);
                        PlayerPrefs.Save();
                        break;
                    }
                case PreviewMode.EditorPrefs:
                    {
                        var valueType = keyValue.Value.GetType();
                        if (valueType == typeof(int))
                            EditorPrefs.SetInt(keyValue.Key, (int)keyValue.Value);
                        else if (valueType == typeof(float))
                            EditorPrefs.SetFloat(keyValue.Key, (float)keyValue.Value);
                        else
                            EditorPrefs.SetString(keyValue.Key, valueString);
                        break;
                    }
                default: Debug.LogError("DataSavePreviewWindow SetValue error: unsupport type=" + _previewMode); break;
            }
        }
    }
}